from django_redis import get_redis_connection

import base64
import pickle


def merge_cart_cookie_to_redis(request, user, response):
    """合并购物车到redis购物车"""

    # 读取cookie中的购物车数据
    cookie_cart_str = request.COOKIES.get('cart')

    # 判断cookie中的购物车数据是否存在，如果存在反转字典；反之直接返回
    if not cookie_cart_str:
        raise response

    # 将 cookie 中的购物车数据转字典
    cookie_cart_str_dict = cookie_cart_str.encode()
    cookie_cart_dict_bytes = base64.b64decode(cookie_cart_str_dict)
    cookie_cart_dict = pickle.loads(cookie_cart_dict_bytes)

    # 读取redis中的购物车数据
    redis_conn = get_redis_connection('cart')
    # 读取hash中的sku-id 和count
    redis_cart_dict = redis_conn.hgetall('cart_%s' % user.id)
    # 读取redisset中的sku-id
    redis_cart_selected = redis_conn.smembers('selected_%s' % user.id)

    # 准备一个新的中间字典：为了收集redis中原有的数据。也为了保证合并的时候redis购物车类型和cookie购物车类型一样
    new_redis_cart_dict = {}
    for sku_id, count in redis_cart_dict.items():
        new_redis_cart_dict[int(sku_id)] = int(count)

    # 遍历cookie中的购物车数据，合并到redis购物车
        for sku_id, cookie_cart in cookie_cart_dict.items():
            new_redis_cart_dict[sku_id] = cookie_cart['count']

            if cookie_cart['selected']:
                # redis—cart-selected：集合对象。add（）方法是直接向集合中添加元素，类似于列表的insert（）方法
                redis_cart_selected.add(sku_id)

    # 将new_redis_cart_dict和redis_cart_selected里面的购物车数据同步到redis
    pl = redis_conn.pipeline()
    pl.hmset('cart_%s' % user.id, new_redis_cart_dict)
    pl.sadd('selected_%s' % user.id, *redis_cart_selected)
    pl.execute()

    # 清空cookie中的购物车
    response.delete_cookie('cart')

    # 一定要将response返回到视图中，在视图中才能将response对象交给用户
    return response